#include "Database.h"
#include <QFile>
#include <QDataStream>
#include <QTextCodec>
#include  <QtCore>
#include <QByteArray>

/*
QDataStream &operator<<(QDataStream &out, const Telephone &x)
{
	out<<x.id <<x.name << x.name_orient << x.camera <<x.card <<x.first <<x.net <<x.price <<x.other <<x.radio <<x.sizes <<x.haveprice;
	return out;
}

QDataStream &operator>>(QDataStream &in, Telephone &x)
{
	in>> x.id >>x.name >>x.name_orient >>x.camera >>x.card >>x.first >>x.net >>x.price >>x.other >>x.radio >>x.sizes >>x.haveprice;
	return in;
}

*/
Database::Database(void)
{
	global = 0;
}

Database::~Database(void)
{
}


int Database::count() const
{
	return data.count();
}
int Database::append(Telephone &phone)
{
	data.append(phone);
	return data.count()-1;
}

int Database::update(const Telephone record)
{
	Telephone rd;
	for (it = data.begin(); it != data.end(); ++it)
	{
		if ((*it).id == record.id)
		{
			rd = record;
			remove(record.id);
			break;
		}
	}
	int pos = 0;
	QVector<Telephone>::iterator ite;
	for (ite = data.begin(); ite != data.end(); ++ite)
	{
		if (*ite > rd)
		{

			break;
		}
		else
			pos ++;
	}

	ite =  data.insert(ite, rd);
	return pos;
}

void Database::remove(int id)
{
	for (it = data.begin(); it != data.end(); ++it)
	{
		if ((*it).id == id)
		{
			it = data.erase(it);
			break;
		}
	}
}

Telephone Database::record(int id)
{
	bool isFind = false;
	for (it = data.begin(); it != data.end(); ++it)
	{
		if ((*it).id == id)
		{
			return *it;
			isFind = true;
		}
	}
	//return NULL;
	return *it;
}

const QVector<PhoneItem> Database::records()
{
	QVector<PhoneItem> item;
	for (it = data.begin(); it != data.end(); ++it)
	{
		item.append(it->toItem());
	}	
	return item;
}

void Database::clear()
{
	data.clear();
}

QString Database::readQString(HANDLE hFile)
{

	QString str;
	const int sizes = 255;
	int size;
	DWORD sizeRead;
	char buffer[sizes];

	*(buffer + str.size()) = 0;
	ReadFile(hFile, (void*)&size, sizeof(int), &sizeRead, NULL);
	if (size == 1)
	{
		str = ("\n");
		return NULL;
	}

	ReadFile(hFile, (void*)buffer, sizeof(char)*(size), &sizeRead, NULL);

	//QString string = QString::fromLocal8Bit(c_str2);
	str.resize(sizeRead);
	str = QString(buffer);
	return str;
}

int Database::writeQString(HANDLE hFile,  QString str)
{

	const int sizes = 255;
	int size;
	DWORD sizeRead;
	char buffer[sizes];

	//buffer = str.fromAscii().data();
	//strcpy(buffer, str.toAscii().data());
	*(buffer + str.size()) = 1;


	size = str.size()+1;
	WriteFile(hFile, (void*)&size, sizeof(int), &sizeRead, NULL);
	if (str != NULL)
	{
		strcpy(buffer,str.toAscii().data());
		WriteFile(hFile, (void*)buffer, sizeof(char)*(size), &sizeRead, NULL);
		return sizeRead;
	}
	return 0;

}

bool Database::save(void)
{
	//QFile file(filename);
	HANDLE hfWirte = CreateFile(TEXT("telephone.db"), GENERIC_WRITE, NULL, NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

	int CountList = data.count();
	DWORD bytesWritten;
	if (CountList == 0)
	{
		CloseHandle(hfWirte);
		DeleteFile(L"telephone.db");
		return true;
	}

	WriteFile(hfWirte, (void*)&CountList, sizeof(int), &bytesWritten, NULL);
	for (it = data.begin(); it != data.end(); ++it)
	{
		writeQString(hfWirte, (*it).name);
		WriteFile(hfWirte, (void*)&(*it).name_orient, sizeof(int), &bytesWritten, NULL);
		writeQString(hfWirte, (*it).sizes);
		WriteFile(hfWirte, (void*)&(*it).radio, sizeof(bool), &bytesWritten, NULL);
		WriteFile(hfWirte, (void*)&(*it).card, sizeof(bool), &bytesWritten, NULL);
		WriteFile(hfWirte, (void*)&(*it).net, sizeof(bool), &bytesWritten, NULL);
		WriteFile(hfWirte, (void*)&(*it).haveprice, sizeof(bool), &bytesWritten, NULL);
		writeQString(hfWirte, (*it).other);
		WriteFile(hfWirte, (void*)&(*it).first, sizeof(bool), &bytesWritten, NULL);

		WriteFile(hfWirte, (void*)&(*it).price, sizeof(int), &bytesWritten, NULL);
		WriteFile(hfWirte, (void*)&(*it).camera, sizeof(double), &bytesWritten, NULL);
		WriteFile(hfWirte, (void*)&(*it).id, sizeof(int), &bytesWritten, NULL);
	}
	CloseHandle(hfWirte);
	return true;
}

bool Database::load(void)
{
	HANDLE hfRead = CreateFile(TEXT("telephone.db"), GENERIC_READ, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	int CountPhone;
	DWORD bytesWritten;

	BOOL br = ReadFile(hfRead, (void*)&CountPhone, sizeof(int),&bytesWritten, NULL);
	if (!br || bytesWritten == 0)
	{
		CloseHandle(hfRead);
		return 0;
	}

	for (int i = 0; i < CountPhone; i++)
	{
		Telephone testphone;
		testphone.name = readQString(hfRead);
		ReadFile(hfRead, (void*)&testphone.name_orient, sizeof(int), &bytesWritten, NULL);
		testphone.sizes = readQString(hfRead);
		ReadFile(hfRead, (void*)&testphone.radio, sizeof(bool), &bytesWritten, NULL);
		ReadFile(hfRead, (void*)&testphone.card, sizeof(bool), &bytesWritten, NULL);
		ReadFile(hfRead, (void*)&testphone.net, sizeof(bool), &bytesWritten, NULL);
		ReadFile(hfRead, (void*)&testphone.haveprice, sizeof(bool), &bytesWritten, NULL);
		testphone.other = readQString(hfRead);
		ReadFile(hfRead, (void*)&testphone.first, sizeof(bool), &bytesWritten, NULL);
		ReadFile(hfRead, (void*)&testphone.price, sizeof(int), &bytesWritten, NULL);
		ReadFile(hfRead, (void*)&testphone.camera, sizeof(double), &bytesWritten, NULL);
		ReadFile(hfRead, (void*)&testphone.id, sizeof(int), &bytesWritten, NULL);

		append(testphone);
	}
	CloseHandle(hfRead);
	return true;

}